package org.grow.secure.config;

import org.grow.secure.entity.UserInfo;
import org.grow.secure.service.AuthHandler;
import org.grow.secure.service.NormalAccessDecision;
import org.grow.secure.service.UrlDataSource;
import org.grow.secure.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Collection;

/**
 * @Author: xwg
 * @CreateDate: 21-7-15
 */

@EnableWebSecurity
public class SecurityCenter extends WebSecurityConfigurerAdapter {

//    UserInfo => UserDetails =>Principle => Auth Authentication
//    UserInfoService  => UserDetailsService loadUserByUsername
//    AuthSuccessHandler AuthFailureHandler
//    PasswordEncoder
//    登录 =》 验证身份获取cookie
//    SPA  single page application 装载应用程序
//
    @Autowired
    private AuthHandler authHandler;
    @Autowired
    private UrlDataSource urlDataSource;
    @Autowired
    private NormalAccessDecision normalAccessDecision;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().disable();
        http.csrf().disable();
        http.httpBasic().disable();

        http.authorizeRequests()
                .antMatchers("/**")
                .permitAll();
        http.formLogin()
//                UsernamePasswordAuthenticationFilter
                .loginProcessingUrl("/login")
                .usernameParameter("username")
                .passwordParameter("password")
                .successHandler(authHandler)
                .failureHandler(authHandler);
//                .withObjectPostProcessor(new ObjectPostProcessor<UsernamePasswordAuthenticationFilter>() {
//                    @Override
//                    public <O extends UsernamePasswordAuthenticationFilter> O postProcess(O o) {
//                        o.setUsernameParameter("ddd");
//                        o.setPasswordParameter("sss");
//                        o.setFilterProcessesUrl();
//                        o.setAuthenticationSuccessHandler();
//                        o.setPostOnly();
//                    }
//                })



        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(-1);
        userInfo.setUsername("anonymous007");
        userInfo.setPassword("666");
        userInfo.setLastLoginTime(LocalDateTime.now());
        userInfo.setIsEnable(true);
        userInfo.setNickname("某匿名用户");
        http.anonymous().principal(userInfo);

        http.logout()
                .logoutUrl("/logout")
                .deleteCookies("JSESSIONID")
                .invalidateHttpSession(true)
                .logoutSuccessHandler((request, response, auth) -> {
                    response.setStatus(200);
                    response.getWriter().println("good bye "+auth.getName());
                });
//        FilterSecurityInterceptor
        http.authorizeRequests()
                .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
                    @Override
                    public <O extends FilterSecurityInterceptor> O postProcess(O o) {
//                        负责权限拦截第二步 根据url 查询出 roles
                        o.setSecurityMetadataSource(urlDataSource);
//                        负责权限拦截第三步 决定用户是否有权访问 比较第一步中的roles 和第二步中的roles 有无交集
                        o.setAccessDecisionManager(normalAccessDecision);
                        return o;
                    }
                }).anyRequest().authenticated();

//        第四步
        http.exceptionHandling()
                .accessDeniedHandler((req, res, e) -> {
                    res.setStatus(930);
                    res.getWriter().println(e.getMessage()+" 统一处理完毕");
                });

    }
    @Autowired
    private UserInfoService userInfoService;
//第二步的要求
    @Override
    protected UserDetailsService userDetailsService() {
        return userInfoService;
    }


}
